#!/bin/sh
# Do a little magic to run perl from anywhere in your path.

lines=`cat $0 | wc -l`
lines=`expr $lines - 16`
if (test -z "$TMPDIR") then
    TMPDIR=$HOME
fi
tail -$lines $0 1> $TMPDIR/visitfelperl$$ 2>/dev/null
if (test $? -ne 0) then
    tail --lines=$lines $0 1>> $TMPDIR/visitfelperl$$
fi
echo "__END__" >> $TMPDIR/visitfelperl$$
echo "$0 $*" >> $TMPDIR/visitfelperl$$
exec perl $TMPDIR/visitfelperl$$ $0 ${1+"$@"}

unlink $0;
$0 = shift @ARGV;

###############################################################################
#
# Purpose:
#   This is the primary front end launcher for programs in the VisIt toolchain.
#   It is separate from the pieces than change on a per-version basis.
#
#   More specifically:
#     Parse out version arguments and determine the version to run.
#     Fall back to legacy launcher if needed.
#     Use argv[0] (i.e. $0) to determine if which program is being run.
#     Determine if someone is trying to use the old "visit -prog" method
#         of launching tools, and if so both warn them and fix things.
#     Keep track of mixing of public and private versions of VisIt.
#     Finally, if all goes well, launch the "internallauncher" which is
#         allowed to contain version-specific pieces.
#
# Note: Place NO version specific code here!
#       Place NOTHING that requires backwards compatibility code here.
#       ...
#       The only exception in this file is that which is just enough to
#       fall back to the pre-version-specific visit launcher script, and
#       by the time you read this note, that should not require changes.
#
# Programmer:  Jeremy Meredith
# Date      :  December  8, 2004
#
# Modifications:
#    Jeremy Meredith, Mon Dec 13 13:38:05 PST 2004
#    It was erroneously grepping for partial version name matches.
#    E.g. it would think 1.4 had an internallauncher if it found
#    one for version 1.4.1.  This caused old versions to fail to run.
#
#    Jeremy Meredith, Fri Jan  7 13:48:45 PST 2005
#    My last fix wasn't completely portable across perl versions.  I fixed it.
#
#    Jeremy Meredith, Tue Apr 19 08:36:36 PDT 2005
#    Made sure both "-convert" and "-visitconvert" work.
#
#    Brad Whitlock, Tue Sep 19 17:48:12 PST 2006
#    Added -mpeg2encode, -composite, -transition.
#
###############################################################################


# -----------------------------------------------------------------------------
#                                 Setup
# -----------------------------------------------------------------------------

# Set a secure and reasonable path
$ENV{PATH} = join ':' , ("$ENV{PATH}","/bin","/usr/bin","/usr/sbin",
                         "/usr/local/bin", "/usr/bsd","/usr/ucb" );

# set base directory
chomp( $progname= `basename $0`);
chomp( $progdir = `dirname $0` );
chomp( $cwd     = `pwd`        );

# Add the program directory to the path!
$ENV{PATH} = join ':' , ("$progdir", "$ENV{PATH}");

for ($progdir) {
    /^\//  && do { $tmpdir = $progdir; last; }; # starts with `/'
    /^\.$/ && do { $tmpdir = $cwd; last; };     # is exactly  `.'
    $tmpdir = "$cwd/$progdir";
}

# strip single . paths
while ($tmpdir =~ s|(/\./)|/|) {}

# compress out remaining /dir/.. forms
while ($tmpdir =~ s|(/[^/]+/\.\.)||) {}

# Note: the above ".."-compression is safe because we already determined we
# had an absolute path, we know the substitution goes left-to-right, and
# we cannot legally .. above the root of the directory tree.  If at some
# point these assumptions change, we can use the following line instead,
# which is more complex but makes sure not to compress out /../.. forms.
#while ($tmpdir =~ s@(/([^/.][^/]*|[^/]*[^/.]|[^/]{3,})/\.\.)@@) {}

chomp( $visitdir = `dirname $tmpdir` );

# -----------------------------------------------------------------------------
#                            Parse the arguments
# -----------------------------------------------------------------------------

# Set some defaults.
$want_version = 0;
$ver          = "";
$beta         = 0;
$using_dev    = 0;

# Parse the arguments 
@legacyvisitargs = @ARGV;
@visitargs = ();
while (scalar(@ARGV) > 0) {
    $arg = shift @ARGV;
    if ($arg eq "-v")
    {
        $ver  = shift; $ver_set  = 1;
        die "The '-v' version argument requires a value.\n" if (!defined $ver);
    }
    elsif ($arg eq "-beta")
    {
        $beta = 1;
    }
    elsif ($arg eq "-dv")
    {
        $using_dev = 1;
    }
    elsif ($arg eq "-version")
    {
        $want_version = 1;
    }
    elsif ($arg eq "-xml2atts"        or
           $arg eq "-xml2avt"         or
           $arg eq "-xml2info"        or
           $arg eq "-xml2makefile"    or
           $arg eq "-xml2projectfile" or
           $arg eq "-xml2plugin"      or
           $arg eq "-xml2python"      or
           $arg eq "-xml2window"      or
           $arg eq "-xml2java"        or
           $arg eq "-xmltest"         or
           $arg eq "-xmledit"         or
           $arg eq "-makemili"        or
           $arg eq "-convert"         or
           $arg eq "-visitconvert"    or
           $arg eq "-silex"           or
           $arg eq "-surfcomp"        or
           $arg eq "-text2polys"      or
           $arg eq "-time_annotation")
    {
        $progname = substr($arg, 1);
        print STDERR "NOTE:  Specifying tools as an argument to VisIt is ";
        print STDERR "no longer necessary.\nIn the future, you should ";
        print STDERR "just run '$progname' instead.\n\n";
    }
    elsif ($arg eq "-mpeg2encode"     or
           $arg eq "-mpeg_encode")
    {
        $progname = substr($arg, 1);
    }
    elsif ($arg eq "-composite")
    {
        $progname = "visit_composite";
    }
    elsif ($arg eq "-transition")
    {
        $progname = "visit_transition";
    }
    else
    {
        push @visitargs, $arg;
    }
}

# -----------------------------------------------------------------------------
#                          Find the right version
# -----------------------------------------------------------------------------
# If we have a top-level "exe" directory, then don't bother looking
# for versions to use; this is a development executable.
if (-d "$visitdir/exe")
{
    if ($want_version)
    {
        print STDERR "The version of VisIt in the directory $visitdir/exe/ ".
                     "will be launched.\n";
        exit 0;
    }

    # They may have specified the version, but we need to ignore it
    # because development trees don't have version directories.
    $ver = "";

    # We want to make sure we know if we are trying to launch a public
    # version from under a development version.  Keep track of this.
    # (Note -- don't add it on our own if we're launching a tool.)
    if ($using_dev or $progname eq "visit")
    {
        push @visitargs, "-dv";
    }
}
else
{
    # look for the version-specific visit script to determine viable versions
    @exe = <$visitdir/*/bin/internallauncher>;
    @exeversions = map {m|^$visitdir/(.*?)/|; $_ = $1;} @exe;
    $current_version = readlink("$visitdir/current");
    $beta_version    = readlink("$visitdir/beta");

    if ($want_version)
    {
        if (! defined $current_version)
        {
            print STDERR "There is no current version of VisIt.\n";
            exit 1;
        }

        print STDERR "The current version of VisIt is $current_version.\n";
        exit 0;
    }

    if (! $ver_set)
    {
        if ($beta)
        {
            if (! defined $beta_version)
            {
                print STDERR "There is no beta version of VisIt.\n";
                exit 1;
            }
            $ver = $beta_version;
        }
        else
        {
            if (! defined $current_version)
            {
                print STDERR "There is no current version of VisIt.\n";
                exit 1;
            }

            $ver = $current_version;
        }
    }

    # If there was no internal laucher for that version, then either
    # that version wasn't installed, or it is an old version that
    # didn't have a version-specific launcher script.
    if (! grep /^${ver}$/, @exeversions)
    {
        if (! -d "$visitdir/$ver")
        {
            print STDERR "There is no version '$ver' of VisIt.\n";
            exit 1;
        }

        # Fall back to legacy here; we set a version and didn't have a
        # version-specific launcher script.

        # Legacy tools were launched using the visit script with
        # an argumnet specifying which tool to run.  Fake it here.
        if ($progname ne "visit" and
            grep(m|^\-${progname}|, @legacyvisitargs) == 0)
        {
            push @legacyvisitargs, "-${progname}";
        }

        @legacycmd = ("$visitdir/bin/legacylauncher", @legacyvisitargs);
        exec @legacycmd or die "Can't execute visit legacy script: $!\n";

        # If we ever stop supporting versions before 1.4.1, we can
        # change to the "right" behavior here.
        #print STDERR "Version $ver of does not exist.\n";
        #exit 1;
    }

    # Warn if we mixed public and private development versions.
    if ($using_dev)
    {
        print STDERR "\n";
        print STDERR "WARNING: You are launching a public version of VisIt\n";
        print STDERR "         from within a development version!\n";
        print STDERR "\n";
        push @visitargs, "-dv";
    }

    # The actual visit directory is now version-specific
    $visitdir = "$visitdir/$ver";
}

# -----------------------------------------------------------------------------
#     Set the environment variables needed for the internal visit launcher
# -----------------------------------------------------------------------------
$ENV{VISITVERSION} = $ver;
$ENV{VISITPROGRAM} = $progname;
$ENV{VISITDIR}     = $visitdir;

# -----------------------------------------------------------------------------
#                       Run the internal launcher!
# -----------------------------------------------------------------------------
@visitcmd = ("${visitdir}/bin/internallauncher", @visitargs);
exec @visitcmd or die "Can't execute visit launcher script: $!\n";
